iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
1
Mobile Development

程式初學:Android與Kotlin系列 第 24

Day 24--天氣app(十)取得所在位置 part 2

  • 分享至 

  • xImage
  •  

現在把取得所在位置的功能加入天氣app吧

先宣告須要的變數

class MainActivity : AppCompatActivity(), ILocationPublisher {

    private var PERMISSION_ID = 1000
    lateinit var fusedLocationProviderClient: FusedLocationProviderClient

    companion object {
        lateinit var myLocation: String
    }
    ...

然後在onCreate()呼叫取得位置的函數

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        requestPermission()
        getLastLocation()
        ...

各函數當然要準備好

    private fun checkPermission(): Boolean {
        if (
            ActivityCompat.checkSelfPermission(
                this,
                android.Manifest.permission.ACCESS_COARSE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(
                this,
                android.Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            return true
        }
        return false
    }

    private fun requestPermission() {

        ActivityCompat.requestPermissions(
            this,
            arrayOf(
                android.Manifest.permission.ACCESS_COARSE_LOCATION,
                android.Manifest.permission.ACCESS_FINE_LOCATION
            ),
            PERMISSION_ID
        )
    }

    private fun isLocationEnabled(): Boolean {

        var locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
            LocationManager.NETWORK_PROVIDER
        )
    }

    private fun getLastLocation() {
        if (checkPermission()) {
            if (isLocationEnabled()) {
                fusedLocationProviderClient.lastLocation.addOnCompleteListener { task ->
                    var location: Location? = task.result
                    if (location == null) {
                        newLocationData()
                    } else {
                        Log.d("Debug:", "Your Location:" + location.longitude)
                        myLocation = getCityName(
                            location.latitude,
                            location.longitude
                        )
                    }
                }
            } else {
                Toast.makeText(this, "Please Turn on Your device Location", Toast.LENGTH_SHORT)
                    .show()
            }
        } else {
            requestPermission()
        }
    }

    private val locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            var lastLocation: Location = locationResult.lastLocation
            Log.d("Debug:", "your last last location: " + lastLocation.longitude.toString())
            myLocation = getCityName(
                lastLocation.latitude,
                lastLocation.longitude
            )
        }
    }

    @SuppressLint("MissingPermission")
    private fun newLocationData() {
        var locationRequest = LocationRequest()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 0
        locationRequest.fastestInterval = 0
        locationRequest.numUpdates = 1
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        fusedLocationProviderClient!!.requestLocationUpdates(
            locationRequest, locationCallback, Looper.myLooper()
        )
    }

    fun getCityName(lat: Double, long: Double): String {
        var cityName: String = ""
        var countryName = ""
        var geoCoder = Geocoder(this, Locale.getDefault())
        var Adress = geoCoder.getFromLocation(lat, long, 3)

        cityName = if (Adress.get(0).adminArea.contains("台")) {
            Adress.get(0).adminArea.replace("台", "臺", false)
        } else {
            Adress.get(0).adminArea
        }
        countryName = Adress.get(0).countryName
        Log.d("Debug:", "Your City: " + cityName + " ; your Country " + countryName)
        return cityName
    }

    //debug用,查看位置權限的取得狀態
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == PERMISSION_ID) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d("Debug:", "You have the Permission")
            }
        }
    }

要注意練習時getCityName()原本是給getLastLocation()中的textView
現在改爲設給一個companion object的變數myLocation,因爲還要給fragment用

然後geoCoder取得的城市名"台南"跟opendata的城市名"臺南"有差別
所以也要處理一下

再來想將retrofit取得的各城市資料清單與myLocation當前位置比對後,一開app就可顯示目前位置的天氣

但不知道爲何寫在onCreate()一開始沒法先取得myLocation的值
不知道是否與網路有關,一定有哪裏怪怪的...須要再了解

    override fun onCreate() {
...
        WeatherApi
            .retrofitService
            .getWeather(key = "rdec-key-123-45678-011121314")
            .enqueue(object : retrofit2.Callback<WeatherData> {
                override fun onFailure(call: Call<WeatherData>, t: Throwable) {
                    //Use Timber
                    Log.e("fail", t.message)
                }

                override fun onResponse(
                    call: Call<WeatherData>,
                    response: Response<WeatherData>
                ) {
                    //api response..
                    Log.d("success", response.toString())
                    if (response.isSuccessful) {
                        response.body()?.records?.location?.forEach {
                            Log.d("api", it.toString())
                            weatherList.add(it)
                        }

                        weatherList.forEach { location ->
                            if (location.locationName.contains(myLocation)) {
                                setQueryResult(location)
                            }
                        }
                    }
                }
            })
    }

畫面稍加整理後,最後像這樣


上一篇
Day 23--天氣app(九)取得所在位置 part 1
下一篇
Day 25--Lifecycles and logging(上)
系列文
程式初學:Android與Kotlin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言